#include<condition_variable>
#include<mutex>
#include<future>
#include<thread>
#include<iostream>
#include<queue>

std::queue<int> queue;
std::mutex queueMutex;
std::condition_variable  queueCondVar;


void provider(int val)
{
    for(int i = 0; i < 6; ++i)
    {
        std::lock_guard<std::mutex> lg(queueMutex);
        queue.push(val + i);
    }
    queueCondVar.notify_all();
    std::this_thread::sleep_for(std::chrono::milliseconds(val));
}

void consumer1(int num)
{
    while (true)
    {
        int val;
        {
            std::unique_lock<std::mutex> ul(queueMutex);
            queueCondVar.wait(ul, []
                              { return !queue.empty(); });
            val = queue.front();
            queue.pop();
        }
        std::cout << "consumer----" << num << " : " << val << "\n";
    }
}
void consumer2(int num)
{
    while (true)
    {
        int val;
        {
            std::unique_lock<std::mutex> ul(queueMutex);
            queueCondVar.wait(ul, []
                              { return !queue.empty(); });
            val = queue.front();
            queue.pop();
        }
        std::cout << "consumer----" << num << " : " << val << "\n";
    }
}
int main()
{
    auto f1 = std::async(std::launch::async, provider, 100);
    auto f2 = std::async(std::launch::async, provider, 300);
    auto f3 = std::async(std::launch::async, provider, 500);

    auto c1 = std::async(std::launch::async, consumer1, 1);
    auto c2 = std::async(std::launch::async, consumer2, 2);
}